package day20;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.Reader;
import java.io.Writer;
import java.util.Arrays;

public class Demo01 {
	public static void main(String[] args) {
		test06();
	}

	// 用字符缓冲流进行文本文件复制
	private static void test06() {
		BufferedReader br = null;
		BufferedWriter bw = null;
		try {

			br = new BufferedReader(new FileReader("./src/day10/Demo01.java"));
			bw = new BufferedWriter(new FileWriter("./copy2.txt"));

			String line = null;
			while ((line = br.readLine()) != null) {
				bw.write(line);
				bw.newLine();
				bw.flush();
			}

			System.out.println("success");

		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			try {
				if (br != null)
					br.close();
			} catch (Exception e) {
				e.printStackTrace();
			} finally {
				try {
					if (bw != null)
						bw.close();
				} catch (Exception e2) {
					e2.printStackTrace();
				}
			}
		}

	}

	// 字符缓冲流向文本文件写内容
	private static void test05() {
		BufferedWriter bw = null;
		try {

			bw = new BufferedWriter(new FileWriter("some.txdt"));

			bw.write("hello world");
			bw.newLine();
			bw.write("hello io");
			bw.flush();
			System.out.println("success");

		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			try {
				if (bw != null)
					bw.close();
			} catch (Exception e2) {
				e2.printStackTrace();
			}
		}
	}

	// 字符缓冲流读取文本文件
	private static void test04() {
		BufferedReader br = null;
		try {

			//			Reader r = new FileReader("./src/some.properties");
			//			br = new BufferedReader(r);
			br = new BufferedReader(new FileReader("./src/day19/Demo01.java"));

			//			String line = br.readLine();
			//			System.out.println(line);

			// 只要读取结果不是null
			// 就循环读取
			String line = null;
			while ((line = br.readLine()) != null) {
				System.out.println(line);
			}

		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			try {
				// 当关闭包装流时, 其所包装的节点流会随之关闭
				// 不需要单独关闭
				if (br != null)
					br.close();
			} catch (Exception e2) {
				e2.printStackTrace();
			}
		}

	}

	// 利用字符输入输出流复制文本文件
	private static void test03() {

		// 对一个源文件进行读取操作
		// 对一个目标文件进行写入操作
		// 需要2个流实现
		Reader r = null;
		Writer w = null;
		try {
			r = new FileReader("./src/day19/Demo02.java");
			w = new FileWriter("./copy.txt");

			// 一个字一个字复制
			// 输入流读一个字, 输出流将读到的字写到文件
			//			int i = -1;
			//			while((i = r.read()) != -1) {
			//				w.write(i);
			//				w.flush();
			//			}

			// 用数组复制
			int count = -1;
			char[] arr = new char[100];
			while ((count = r.read(arr)) != -1) {
				// 以数组写入时, 写多少个字符
				// 取决于读到了多少个字符
				w.write(arr, 0, count);
				w.flush();
			}

			System.out.println("success");
		} catch (Exception e) {
			e.printStackTrace();
		} finally {

			// 如果有多个流要关闭, 哪个流先开的, 哪个流先关
			try {
				if (r != null)
					r.close();
			} catch (Exception e2) {
				e2.printStackTrace();
			} finally {
				try {
					if (w != null)
						w.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}

		}

	}

	// 字符流向文本文件写内容
	private static void test02() {
		Writer w = null;
		try {

			// 输出流要操作的目标文件如果不存在
			// 创建流对象时, 会自动创建该文件
			// 创建一个输出流时, 默认是从目标文件的头部开始写入
			// w = new FileWriter("./other.txt");
			// 创建流对象时, 希望从文件尾部追加内容, 而不是从头部写入
			// 在创建流对象时, 需要通过第二参数为true明确
			w = new FileWriter("./other.txt", true);
			// 第二参数为false, 等同于new FileWriter("./other.txt");

			// write方法并不是真正把数据写到目标文件里
			// 而是把程序中的数据写到流中
			// w.write('A');
			// char[] arr = { 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h' };
			// w.write(arr, 3, 4);
			w.write("Hello World");

			// 通过flush方法, 将流中的数据真正写入到文件里
			w.flush();

			System.out.println("success");
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			try {
				if (w != null) {
					// 当输出流正常关闭时, 会自动对流进行刷新
					// 将数据刷新到数据载体
					// 实际开发中建议手动flush
					w.close();
				}
			} catch (Exception e2) {
				e2.printStackTrace();
			}
		}
	}

	// 字符流读取文本文件
	private static void test01() {

		// 注意
		// 1. 流的所有异常不允许throw, 必须try-catch
		// 2. 所有的流在使用完之后, 都必须close()关闭资源
		//    且, close()操作必须放在finally块中
		//    因为要保证不论任何情况, 资源的关闭操作一定能执行

		// 声明流
		Reader r = null;
		try {
			// 创建流对象
			r = new FileReader("./some.txt");

			// 使用流
			//			int i = r.read();
			//			System.out.println((char) i);
			//			i = r.read();
			//			System.out.println((char) i);

			//			int i = -1;
			//			while ((i = r.read()) != -1) {
			//				System.out.println((char) i);
			//			}

			//			int count = -1;
			//			char[] arr = new char[3];
			//			while((count = r.read(arr)) != -1) {
			//				System.out.println(Arrays.toString(arr));
			//			}

			int count = -1;
			char[] arr = new char[10];
			while ((count = r.read(arr, 8, 5)) != -1) {
				System.out.println(Arrays.toString(arr));
			}

		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			// 关闭流资源
			try {
				if (r != null) {
					r.close();
				}
			} catch (IOException e) {
				e.printStackTrace();
			}
		}

		// IO代码套路
		// try外面声明流
		// try中创建流对象, 使用流对象
		// catch中捕捉流异常
		// finally中关闭流资源

		//		声明流
		//		try {
		//			创建流对象;
		//			使用流对象
		//		} catch (Exception e) {
		//			e.printStackTrace();
		//		} finally {
		//			关闭流资源
		//		}

	}
}
